/****************************************************************************************
**  File: Vector2.hpp
**  Author: Asteroth
**  Date: 22/02/2009
****************************************************************************************/

#ifndef __VECTOR2_HPP__
#define __VECTOR2_HPP__

template <class T>
class Vector2x {
public:
	T X, Y;

	Vector2x():							X(0), Y(0) {}
	Vector2x(const Vector2x<T> &vect):	X(vect.X), Y(vect.Y) {}
	Vector2x(T x, T y):					X(x), Y(y) {}

	inline Vector2x<T> &operator = (const Vector2x<T> &set) {
		X = set.X;
		Y = set.Y;
		return *this;
	}

	inline Vector2x<T> &operator += (const Vector2x<T> &add) {
		X += add.X;
		Y += add.Y;
		return *this;
	}

	inline Vector2x<T> &operator -= (const Vector2x<T> &sub) {
		X -= sub.X;
		Y -= sub.Y;
		return *this;
	}

	inline Vector2x<T> operator + (const Vector2x<T> &add) const {
		return Vector2x<T>(X + add.X, Y + add.Y);
	}

	inline Vector2x<T> operator - (const Vector2x<T> &sub) const {
		return Vector2x<T>(X - sub.X, Y - sub.Y);
	}

	inline Vector2x<T> operator - () const {
		return Vector2x<T>(-X, -Y);
	}

	inline Vector2x<T> &operator *= (const T scalar) {
		X *= scalar;
		Y *= scalar;
		return *this;
	}

	inline Vector2x<T> &operator /= (const T scalar) {
		X /= scalar;
		Y /= scalar;
		return *this;
	}

	inline Vector2x<T> operator * (const T scalar) const {
		return Vector2x<T>(X * scalar, Y * scalar);
	}

	inline Vector2x<T> operator / (const T scalar) const {
		return Vector2x<T>(X / scalar, Y / scalar);
	}

	// Dot Product
	inline T operator || (const Vector2x<T> &dot) const {
		return X * dot.X + Y * dot.Y;
	}

	// Normal
	inline Vector2x<T> operator ! () const {
		float len = sqrt(X * X + Y * Y);
		if (len == 0)
			len = 1;
		return Vector2x<T>(X / len, Y / len);
	}

	// Length
	inline T operator ~ () const {
		return sqrt(X * X + Y * Y);
	}

	inline T dot(const Vector2x<T> &dot) const {
		return X * dot.X + Y * dot.Y;
	}

	inline Vector2x<T> normal() const {
		float len = sqrt(X * X + Y * Y);
		if (len == 0)
			len = 1;
		return Vector2x<T>(X / len, Y / len);
	}

	inline T length() const {
		return sqrt(X * X + Y * Y);
	}

	inline Vector2x<T> inverse() const {
		return Vector2x<T>(-X, -Y);
	}

	inline Vector2x<T> rotated(T angle) const {
		T hypotenuse = sqrt(X*X + Y*Y);
		return Vector2x<T>(hypotenuse * cos(angle), hypotenuse * sin(angle));
	}

	inline void normalize() {
		float len = sqrt(X * X + Y * Y);
		if (len > 0)
		{
			X /= len;
			Y /= len;
		}
	}

	inline void invert() {
		X = -X;
		Y = -Y;
	}

	inline void rotate(T angle) {
		T hypotenuse = sqrt(X*X + Y*Y);
		X = hypotenuse * cos(angle);
		Y = hypotenuse * sin(angle);
	}
};

#endif
